const fs=require('fs');
const path=require('path');
class DBManager{
    static articles=null;
    static config=null;
    static editing=null;
    static loading=10;
    static date=new Date();
    static dbFilename=['articles','config','editing'];
    static needWriteBack=false;
    constructor() {
        throw new Error('DBManager is a static class!!!');
    }
    static initialize(callback) {
        this.articlesDir=path.resolve(__dirname,'articles');
        this.databaseDir=path.resolve(__dirname,'database');
        this.loading=this.dbFilename.length;
        this._loadDataBase(this.dbFilename,callback);
    }
    static _loadDataBase(filenames,callback){
        for(const filename of filenames){
            fs.readFile(`${this.databaseDir}/${filename}.json`,'utf-8',function(err,data){
                if(!err){
                    DBManager[filename]=JSON.parse(data);
                    --DBManager.loading;
                    if(DBManager.loading<=0){
                        callback();
                    }
                }else{
                    console.log(`${filename}.json 读取失败`);
                }
            });
        }
    }

    static removeArticle(id){
        if(this.articles[id]){
            this.needWriteBack=true;
            this.config.available.push(id);
            //移除数组
            let article=this.articles[id];
            this.articles[id]=null;
            //移除文件
            
        }
    }

    static readArticle(id,callback){
        fs.readFile(`${this.articlesDir}/${id}/index.json`,'utf-8',function(err,data){
            if(!err){
                callback(data);
            }else{
                callback(null);
            }
        });
    }

    static createArticle(title,callback){
        //分配id
        let id=this.allocId();
        this.editing.push({id,title,date:this.date.toLocaleDateString()});
        this.needWriteBack=true;
        //创建文件
        fs.mkdir(`${this.articlesDir}/${id}/`,function(error){
            if(!error||(error&&error.code=='EEXIST')){
                fs.writeFile(`${this.articlesDir}/${id}/index_back.json`,
                JSON.stringify({title:'title',content:''}),
                function(error){
                    if(error){
                        console.log(`${id}/index_back.json创建失败`);
                    }else if(callback){
                        callback();
                    }
                });
            }
        });
    }

    static saveArticleBack(id,title,content,callback){
        if(!this.editing[id]){
            if(this.articles[id]){
                //创建保存文件
                this.editing[id]={id};
            }else{
                callback(false);
                return;
            }
        }
        this.needWriteBack=true;
        this.editing[id].title=title;
        this.editing[id].date=this.date.toLocaleDateString();
        fs.writeFile(`${this.articlesDir}/${id}/index_back.json`,
            JSON.stringify({title,content}),
            function(err){
                if(err){
                    console.log(err);
                    callback(false);
                }else{
                    callback(true);
                }
            });
    }

    static commitArticle(id,title,content,callback){
        let edited=this.editing[id];
        this.needWriteBack=true;
        if(edited){
            this.editing[id]=null;
            //清理尾端
            if(id==this.editing.length-1){
                let index=id;
                while(index>=0&&!this.editing[index])--index;
                this.editing.length=index+1;
            }
            edited.title=title;
            edited.date=this.date.toLocaleDateString();

            //editing转移到articles
            if(id!=this.articles.length){
                this.articles[id]=edited;
            }else{
                this.articles.push(edited);
            }
        }else{
            this.articles[id].title=title;
            this.articles[id].date=this.date.toLocaleDateString();
        }
        
        
        //index_back转移到index
        fs.writeFile(`${this.articlesDir}/${id}/index.json`,
            JSON.stringify({title,content}),
            function(error){
                if(error){
                    console.log(error);
                    callback(false);
                }else{
                    callback(true);
                }
            }
        );
    }



/////工具
    static close(callback){
        if(this.needWriteBack){
            this.loading=this.dbFilename.length;
            //写回articles
            for(const filename of this.dbFilename){
                fs.writeFile(`${DBManager.databaseDir}/${filename}.json`,
                    JSON.stringify(DBManager[filename]),
                    function(error){
                        --DBManager.loading;
                        if(DBManager.loading<=0){
                            callback();
                        }
                    }
                )
            }
        }else{
            callback();
        }
    }
    static allocId(){
        if(this.config.available.length){
            return this.config.available.pop();
        }
        return this.config.next++;
    }
    static exist(id){
        return !!this.articles[id];
    }
    static isReady(){
        return !this.loading;
    }
}

exports.DBManager=DBManager;